#include <iostream>
#include <thread>
#include <mutex>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <cstring>

using namespace std;

// class MyLock
// {
// public:
//     MyLock(std::mutex mutex) : w_mutex(mutex)
//     {
//         w_mutex.lock();
//     }

//     ~MyLock()
//     {
//         w_mutex.unlock();
//     }
// private:
//     mutex w_mutex;
// };

class FuncWriter
{
public:
    FuncWriter(const string &filename)
    {
        if ((m_fd = open(filename.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0655)) < 0)
        {
            perror("open file error!");
            exit(1);
        }
    }

    void write_data1()
    {
        while (1)
        {
            // w_mutex.lock();

            {
                lock_guard<std::mutex> lock(w_mutex);
                write(m_fd, "hello", 5);
                write(m_fd, "world", 5);
                write(m_fd, "\n", 1);
                // w_mutex.unlock();  //容易忘记释放锁
            }
        }
    }

    void write_data2()
    {
        while (1)
        {
            // w_mutex.lock();
            {
                //w_mutex.lock();
                //unique_lock<std::mutex> lock(w_mutex,std::adopt_lock);
                //lock.lock();
                
                write(m_fd, "hhhhh", 5);
                write(m_fd, "wwwww", 5);
                write(m_fd, "\n", 1);
            } // w_mutex.unlock();
        }
    }

    void func()
    {
        int num = 5;
        while(1)
        {
            // mutex1.lock();
            // sleep(1);
            // mutex2.lock();
            std::lock(mutex1, mutex2);
            num++;
            cout << "num =" << num << endl;
            sleep(1);
            mutex2.unlock();
            mutex1.unlock();
        }
    }
    
    void func2()
    {
        int num = 5;
        while(1)
        {
            // mutex2.lock();
            // sleep(1);
            // mutex1.lock();
            std::lock(mutex1, mutex2);
            num++;
            cout << "num2 =" << num << endl;
            sleep(1);
            mutex2.unlock();
            mutex1.unlock();
        }
    }
    ~FuncWriter()
    {
        close(m_fd);
    }

private:
    int m_fd;
    mutex w_mutex;
    mutex mutex1;
    mutex mutex2;
};

int main(int argc, char **argv)
{
    FuncWriter fw("a.txt");
    thread t1(&FuncWriter::write_data1, &fw); // 互斥锁：对象的引用
    thread t2(&FuncWriter::write_data2, &fw);
    thread t3(&FuncWriter::func, &fw);
    thread t4(&FuncWriter::func2, &fw);

    pause();
    return 0;
}